package sistemaDefensivo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Stack;
import comunicacion.Servidor;
import concurrencia.SemaforoBinario;
import escenario.Escenario;
import escenario.Posicion;

public class SistemaBateriaMisiles implements Runnable {

	private int numeroBateria = 0;
	private ArrayList <BateriaDeMisiles> bateriasDeMisiles;
	private Servidor serverSistBat;
	protected SemaforoBinario lock;
	private Escenario esc;
	private DisparadorBaterias disparador;
	private Thread hiloDisparador;


	private int[] disparaN = {-1,0,0,0,-1,0,0,0,1,0,0,0};
	private int[] disparaE = {0,-1,0,0,0,-1,0,0,0,1,0,0};
	private int[] disparaS = {0,0,-1,0,0,0,-1,0,0,0,1,0};
	private int[] disparaO = {0,0,0,-1,0,0,0,-1,0,0,0,1};
	private int[] n_e= {-1,1,0,0,0,0,0,0,0,0,0,0};
	private int[] e_s = {0,-1,1,0,0,0,0,0,0,0,0,0};
	private int[] s_o= {0,0,-1,1,0,0,0,0,0,0,0,0};
	private int[] o_n= {1,0,0,-1,0,0,0,0,0,0,0,0};
	private int[] habilitadorN= {0,0,0,0,1,0,0,0,-1,0,0,0};
	private int[] habilitadorE= {0,0,0,0,0,1,0,0,0,-1,0,0};
	private int[] habilitadorS= {0,0,0,0,0,0,1,0,0,0,-1,0};
	private int[] habilitadorO= {0,0,0,0,0,0,0,1,0,0,0,-1};
	private int[] detectaN= {1,0,0,0,0,0,0,0,0,0,0,0};
	private int[] detectaE= {0,1,0,0,0,0,0,0,0,0,0,0};
	private int[] detectaS= {0,0,1,0,0,0,0,0,0,0,0,0};
	private int[] detectaO= {0,0,0,1,0,0,0,0,0,0,0,0};
	
//    							  (CN,CE,CS,CO,HN,HE,HS,HO,DN,DE,DS,DO)
	private int[] vectorMarcado = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0};
	
	private Stack<DatosMisil> pilaN = new Stack<DatosMisil>();
	private Stack<DatosMisil> pilaE = new Stack<DatosMisil>();
	private Stack<DatosMisil> pilaS = new Stack<DatosMisil>();
	private Stack<DatosMisil> pilaO = new Stack<DatosMisil>();

	private Stack<String> pilaVectorMarcado = new Stack<String>();
	
	public SistemaBateriaMisiles(Escenario es){
		bateriasDeMisiles = new ArrayList <BateriaDeMisiles>();
		this.esc = es;
		serverSistBat = new Servidor(6000);		
		lock = new SemaforoBinario(1);
		disparador = new DisparadorBaterias(this);
		hiloDisparador = new Thread(disparador);
	}

	public Stack<String> getPilaVectorMarcado() {
		return pilaVectorMarcado;
	}

	public void setPilaVectorMarcado(Stack<String> pilaVectorMarcado) {
		this.pilaVectorMarcado = pilaVectorMarcado;
	}
	
	public int[] getVectorMarcado() {
		return vectorMarcado;
	}

	public void addBateriaDeMisiles(BateriaDeMisiles bm){
		bateriasDeMisiles.add(bm);
	}
	
	public int getCantidadBateriasMisiles(){
		return bateriasDeMisiles.size();
	}
	
	public void crearBateria(double radio, double tita, double fi){
		BateriaDeMisiles batTemp = new BateriaDeMisiles();
		batTemp.setEscenario(this.esc);
		batTemp.setPosicion(new Posicion(radio, Math.toRadians(tita), Math.toRadians(fi)));
		batTemp.setId(numeroBateria);
		addBateriaDeMisiles(batTemp);
		Thread hiloBatTemp = new Thread(bateriasDeMisiles.get(numeroBateria));
		hiloBatTemp.start();
		numeroBateria++;
	}	
	
	public void dispararTransicion(int[] tran){
		for(int i=0; i<12; i++){		
			vectorMarcado[i] = tran[i] + vectorMarcado[i];
		}
	}

	public boolean verificador(int[] tran){
		int[] marcadoAux = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		for(int i=0; i<12; i++){		
			marcadoAux[i] = tran[i] + vectorMarcado[i];
			if(marcadoAux[i] == -1){
				return false;
			}
		}
		return true;
	}
	
	public void lanzarDefensa(String ipRespAttk, int portRespAttk, int coordenadaOrigen){
		DatosMisil dato = new DatosMisil(ipRespAttk, portRespAttk, coordenadaOrigen);
		switch(coordenadaOrigen){
			case 0:
				lock.cerrar();
				dispararTransicion(detectaN);
				pilaN.push(dato);
				lock.abrir();
				break;
			case 1: 
				lock.cerrar();
				dispararTransicion(detectaE);
				pilaE.push(dato);
				lock.abrir();
				break;
			case 2: 
				lock.cerrar();
				dispararTransicion(detectaS);
				pilaS.push(dato);
				lock.abrir();
				break;
			case 3: 
				lock.cerrar();
				dispararTransicion(detectaO);
				pilaO.push(dato);
				lock.abrir();
				break;
		}
	}
	
	public void dispararNorte(){
		lock.cerrar();
		if(verificador(disparaN) && !pilaN.isEmpty()){
			dispararTransicion(disparaN);
			DatosMisil temp = pilaN.pop();
			bateriasDeMisiles.get(0).lanzarMisil(temp.getIpRespAttk(), temp.getPortRespAttk());
			TemporizadorBateria temporizadorNorte = new TemporizadorBateria(this, lock, habilitadorN);
			Thread hilo = new Thread(temporizadorNorte);
			hilo.start();
			System.out.println("\nSISTEMA DE BATERIAS dice ================> Se disparo la bateria NORTE.");		
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}
	
	public void dispararNorteEste(){
		lock.cerrar();
		if(verificador(n_e) && !pilaN.isEmpty()){
			dispararTransicion(n_e);
			pilaE.push(pilaN.pop());
			System.out.println("\nSISTEMA DE BATERIAS dice ================> La Bateria NORTE no se encuentra Habilitada.");
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}

			
	public void dispararEste(){
		lock.cerrar();
		if(verificador(disparaE) && !pilaE.isEmpty()){
			dispararTransicion(disparaE);
			DatosMisil temp = pilaE.pop();
			bateriasDeMisiles.get(1).lanzarMisil(temp.getIpRespAttk(), temp.getPortRespAttk());
			TemporizadorBateria temporizadorEste = new TemporizadorBateria(this, lock, habilitadorE);
			Thread hilo = new Thread(temporizadorEste);
			hilo.start();
			System.out.println("\nSISTEMA DE BATERIAS dice ================> Se disparo la bateria ESTE.");		
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}

	public void dispararEsteSur(){
		lock.cerrar();
		if(verificador(e_s) && !pilaE.isEmpty()){
			dispararTransicion(e_s);
			pilaS.push(pilaE.pop());
			System.out.println("\nSISTEMA DE BATERIAS dice ================> La Bateria ESTE no se encuentra Habilitada.");
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}
				
	public void dispararSur(){
		lock.cerrar();
		if(verificador(disparaS) && !pilaS.isEmpty()){
			dispararTransicion(disparaS);
			DatosMisil temp = pilaS.pop();
			bateriasDeMisiles.get(2).lanzarMisil(temp.getIpRespAttk(), temp.getPortRespAttk());
			TemporizadorBateria temporizadorSur = new TemporizadorBateria(this, lock, habilitadorS);
			Thread hilo = new Thread(temporizadorSur);
			hilo.start();
			System.out.println("\nSISTEMA DE BATERIAS dice ================> Se disparo la bateria SUR.");		
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}
			
	public void dispararSurOeste(){
		lock.cerrar();
		if(verificador(s_o) && !pilaS.isEmpty()){
			dispararTransicion(s_o);
			pilaO.push(pilaS.pop());
			System.out.println("\nSISTEMA DE BATERIAS dice ================> La Bateria SUR no se encuentra Habilitada.");
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}

	public void dispararOeste(){
		lock.cerrar();
		if(verificador(disparaO) && !pilaO.isEmpty()){
			dispararTransicion(disparaO);
			DatosMisil temp = pilaO.pop();
			bateriasDeMisiles.get(3).lanzarMisil(temp.getIpRespAttk(), temp.getPortRespAttk());
			TemporizadorBateria temporizadorOeste = new TemporizadorBateria(this, lock, habilitadorO);
			Thread hilo = new Thread(temporizadorOeste);
			hilo.start();
			System.out.println("\nSISTEMA DE BATERIAS dice ================> Se disparo la bateria OESTE.");		
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}
		
	public void dispararOesteNorte(){
		lock.cerrar();
		if(verificador(o_n) && !pilaO.isEmpty()){
			dispararTransicion(o_n);
			pilaN.push(pilaO.pop());
			System.out.println("\nSISTEMA DE BATERIAS dice ================> La Bateria OESTE no se encuentra Habilitada.");
//			System.out.println("\nEl vector de marcado actual es ==========>  " + Arrays.toString(vectorMarcado));
			pilaVectorMarcado.push(Arrays.toString(vectorMarcado));
		}
		lock.abrir();
	}

	public void run(){
		System.out.println("Se inicia la ejecucion del Sistema de Baterias");
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		crearBateria(10, 90, 0);
		crearBateria(10, 90, 90);
		crearBateria(10, 90, 180);
		crearBateria(10, 90, 270);
		serverSistBat.abrirServidor();
		hiloDisparador.start();	
//		System.out.println("\nEl vector de marcado inicial es =========>  " + Arrays.toString(vectorMarcado));
		while(true){
			serverSistBat.conectarMulti(this);
		}
	}
}